package me.helllp.book.concurrent.ch03;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * Fork/Join模型
 * 
 * @author Administrator
 *
 */
public class CountTask extends RecursiveTask<Long>{
	private static final long serialVersionUID = -3027550999985692311L;
	
	private static final int THRESHOLD = 10000;
	private long start;
	private long end;
	
	public CountTask(long start, long end){
		this.start = start;
		this.end = end;
	}
	
	@Override
	public Long compute(){
		long sum = 0;
		boolean canCompute = (end - start) < THRESHOLD;
		
		if(canCompute){
			for(long i=start; i<=end; i++){
				sum += i;
			}
		}else{
			long step = (end - start) / 100;
			List<CountTask> subTasks = new ArrayList<CountTask>();
			
			long pos = start;
			
			for(int i=0; i<100; i++){
				long lastOne = pos + step;
				
				if(lastOne > end){
					lastOne = end;
				}
				
				CountTask subTask = new CountTask(pos, lastOne);
				pos += step + 1;
				
				subTasks.add(subTask);
				subTask.fork();
			}
			
			for(CountTask t : subTasks){
				sum += t.join();
			}
		}
		
		return sum;
	}
	
	public static void main(String[] args) {
		ForkJoinPool forkJoniPool = new ForkJoinPool();
		CountTask task = new CountTask(0, 1024L);
		
		ForkJoinTask<Long> result = forkJoniPool.submit(task);
		
		
		try {
			long res = result.get();
			System.out.println("Sum = " + res);
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
		
	}
}
